import axios from 'axios'
import { message } from 'ant-design-vue'
import store from '../store/index'

const defaultInstance = getInstance()

// 异常拦截处理器
const errorHandler = (error) => {
    const response = error.response
    message.error('请求失败')
    if (response.status === 401) {
        // 清空本地Token并跳转登陆页面
        localStorage.clear()
        message.error('Token已过期，请重新登陆')
        setTimeout(() => {
            window.location.replace(window.location.origin)
        }, 2000)
    } else {
        return Promise.reject(error)
    }
}

function defaultRequestSuccessFn(config) {
    let token = localStorage.getItem('token')
    if (token) config.headers.authorization = token
    return config
}

function defaultRequestErrorFn(error) {
    return errorHandler(error)
}

function defaultResponseSuccessFn(response) {
    const {isShowSuccessMessage} = response.config || {}
    const code = response.data.code
    if (code === 200) {
        if (isShowSuccessMessage) {
            message.success(response.data.message || '操作成功')
        }
        const {responseType} = response.config
        if (responseType === 'Blob') {
            return response
        } else {
            return response.data
        }
    } else {
        message.error(response.data.message || '请求失败')
        return Promise.reject(response.data)
    }

}

function defaultResponseErrorFn(error) {
    return errorHandler(error)
}

function openLoading() {
    store.dispatch('common/showLoading')
}

function closeLoading() {
    store.dispatch('common/hideLoading')
}

// 提供默认拦截器，支持传入自定义拦截器
// 增加loading 和 timeout处理
export function getInstance(config = {}) {
    const queue = {}
    const {
        baseURL,
        timeout,
        requestSuccessFn,
        requestErrorFn,
        responseSuccessFn,
        responseErrorFn
    } = config

    const service = axios.create({
        baseURL: baseURL || '/api',
        timeout: timeout || 30000
    })

    service.interceptors.request.use(
        (config) => {
            const { loading, url } = config

            if(loading && Object.keys(queue).length === 0) {
                openLoading()
            }

            queue[url] = url

            if (typeof requestSuccessFn === 'function') {
                return requestSuccessFn(config)
            } else {
                return defaultRequestSuccessFn(config)
            }
        },
        (error) => {
            closeLoading()

            if (typeof requestErrorFn === 'function') {
                return requestErrorFn(error)
            } else {
                return defaultRequestErrorFn(error)
            }
        }
    )

    service.interceptors.response.use(
        (response) => {
            delete queue[response.config.url]
            if (Object.keys(queue).length === 0) {
                closeLoading()
            }

            if (typeof responseSuccessFn === 'function') {
                return responseSuccessFn(response)
            } else {
                return defaultResponseSuccessFn(response)
            }
        },
        (error) => {
            closeLoading()

            if (typeof responseErrorFn === 'function') {
                return responseErrorFn(error)
            } else {
                return defaultResponseErrorFn(error)
            }
        }
    )

    return service
}

export default defaultInstance

